package com.simp.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.simp.dto.SysDictDto;
import com.simp.entity.SysDictEntity;
import com.simp.expection.GlobalException;
import com.simp.mapper.SysDictMapper;
import com.simp.page.PageVO;
import com.simp.page.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @author pan.shun
 * @since 2022/3/14 16:48
 */
@Slf4j
@Service
public class SysDictService extends ServiceImpl<SysDictMapper, SysDictEntity> {

    public PageVO<SysDictEntity> queryDictPageList(SysDictDto sysDictDto) {
        LambdaQueryWrapper<SysDictEntity> queryWrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmpty(sysDictDto.getCode())) {
            queryWrapper.like(SysDictEntity::getCode, sysDictDto.getCode()).or().like(SysDictEntity::getName, sysDictDto.getCode());
        }
        if (!StringUtils.isEmpty(sysDictDto.getName())) {
            queryWrapper.like(SysDictEntity::getName, sysDictDto.getName());
        }
        queryWrapper.eq(SysDictEntity::getParentId, "0");
        queryWrapper.orderByDesc(SysDictEntity::getOrderNum);
        IPage<SysDictEntity> iPage = this.page(new Page<>(sysDictDto.getCurrent(), sysDictDto.getSize()), queryWrapper);
        return new PageVO<>(iPage);
    }

    @Transactional(rollbackFor = Exception.class)
    public void addOrUpdate(SysDictEntity sysDictEntity) {
        checkRepeated(sysDictEntity);
        if (StringUtils.isEmpty(sysDictEntity.getId())) {
            this.save(sysDictEntity);
        } else {
            this.updateById(sysDictEntity);
        }
    }

    /**
     * 字典编码或名称重复判断
     */
    private void checkRepeated(SysDictEntity sysDictEntity) {
        if (StringUtils.isEmpty(sysDictEntity.getId())) {
            if (sysDictEntity.getParentId().equals("0")) {
                // 新增
                int count = this.baseMapper.addCheckChildrenRepeated(sysDictEntity.getParentId(), sysDictEntity.getName(), sysDictEntity.getCode());
                if (count != 0) {
                    throw new GlobalException("字典名称或编码不能重复");
                }
            } else {
                // 子集新增
                int count = this.baseMapper.addCheckChildrenRepeated(sysDictEntity.getParentId(), sysDictEntity.getName(), null);
                if (count != 0) {
                    throw new GlobalException("字典名称不能重复");
                }
            }

        } else {
            if (sysDictEntity.getParentId().equals("0")) {
                // 修改
                int count = this.baseMapper.updateCheckChildrenRepeated(sysDictEntity.getParentId(), sysDictEntity.getName(), sysDictEntity.getCode(), sysDictEntity.getId());
                if (count != 0) {
                    throw new GlobalException("字典名称或编码不能重复");
                }
            } else {
                // 修改
                int count = this.baseMapper.updateCheckChildrenRepeated(sysDictEntity.getParentId(), sysDictEntity.getName(), null, sysDictEntity.getId());
                if (count != 0) {
                    throw new GlobalException("字典名称不能重复");
                }
            }

        }
    }


    public void removeDictById(String ids) {
        List<String> idList = Arrays.asList(ids.split(","));
        List<SysDictEntity> dictList = this.listByIds(idList);

        Set<String> childrenIdList = new HashSet<>();

        dictList.forEach(r -> {
            if (r.getParentId().equals("0")) {
                storeChildren(r.getId(), childrenIdList);
            }
        });
        this.removeByIds(idList);

        // 将子集也给删掉
        if (!CollectionUtils.isEmpty(childrenIdList)) {
            this.removeByIds(childrenIdList);
        }
    }

    private void storeChildren(String pid, Set<String> childrenIdList) {
        LambdaQueryWrapper<SysDictEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(SysDictEntity::getId);
        queryWrapper.eq(SysDictEntity::getParentId, pid);
        List<SysDictEntity> childrenList = this.list(queryWrapper);
        childrenList.forEach(r -> {
            childrenIdList.add(r.getId());
        });
    }


    public R getChildrenDictByCode(String code) {
        LambdaQueryWrapper<SysDictEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDictEntity::getCode, code);
        queryWrapper.eq(SysDictEntity::getParentId, "0");
        SysDictEntity sysDictEntity = this.getOne(queryWrapper);
        if (null == sysDictEntity) {
            throw new GlobalException("当前字典编码不存在");
        }
        LambdaQueryWrapper<SysDictEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDictEntity::getParentId, sysDictEntity.getId());
        return R.success(this.list(wrapper));
    }


    public R getChildrenDictById(String id) {
        SysDictEntity parentDict = this.getById(id);
        LambdaQueryWrapper<SysDictEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(SysDictEntity::getName, SysDictEntity::getValue, SysDictEntity::getId);
        queryWrapper.eq(SysDictEntity::getParentId, id);
        queryWrapper.orderByDesc(SysDictEntity::getOrderNum);
        List<SysDictEntity> list = this.list(queryWrapper);
        list.forEach(r -> {
            r.setCode(parentDict.getCode());
        });
        return R.success(list);
    }
}
